#ifndef _MY_ISTREAM_ITERATOR_H_
#define _MY_ISTREAM_ITERATOR_H_

#include <cstddef>
#include <istream>
#include <iterator>
#include <string>

using namespace std;

template<typename T, typename CharT = char, typename Traits = char_traits<CharT>, typename Distance = ptrdiff_t>
class my_istream_iterator : public iterator<input_iterator_tag, T, Distance, const T*, const T&> {
	public:
		typedef CharT char_type;
		typedef Traits traits_type;
		typedef basic_istream<CharT, Traits> istream_type;
		
		my_istream_iterator();
		my_istream_iterator(istream_type& is);
		my_istream_iterator(const my_istream_iterator& orig) = default;
		~my_istream_iterator();
		
		const T operator * ();
		T* operator -> ();
		const my_istream_iterator<T, CharT, Traits, Distance>& operator ++ ();
		my_istream_iterator<T, CharT, Traits, Distance> operator ++ (int);
		
		template<typename T1, typename CharT1, typename Traits1, typename Distance1>
		friend bool operator == (const my_istream_iterator<T1, CharT1, Traits1, Distance1>& lhs, const my_istream_iterator<T1, CharT1, Traits1, Distance1>& rhs);
		
		template<typename T1, typename CharT1, typename Traits1, typename Distance1>
		friend bool operator != (const my_istream_iterator<T1, CharT1, Traits1, Distance1>& lhs, const my_istream_iterator<T1, CharT1, Traits1, Distance1>& rhs);
		
	protected:
		my_istream_iterator(istream_type* is, const T* data, const bool ok);
		void read();
		
	private:
		istream_type* is;
		T* data;
		bool eof;
};

#include "my_istream_iterator.tcc"

#endif

